﻿package igz.fleaxy.ui.calendar 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.media.SoundChannel;
	import igz.fleaxy.events.CommEvent;
	import igz.fleaxy.Fleaxy;
	import igz.fleaxy.net.Comm;
	import igz.fleaxy.ui.ButtonUi;
	import igz.fleaxy.ui.form.input.Input;
	import igz.fleaxy.ui.LinkUi;
	import igz.fleaxy.ui.text.LabelUi;
	import igz.fleaxy.util.DateTimeFormat;
	import igz.fleaxy.util.DateTimeTypes;
	import igz.fleaxy.util.DateTimeUtil;
	import igz.fleaxy.util.ObjectUtil;
	import igz.fleaxy.util.RegExpType;
	import igz.fleaxy.util.SpriteUtil;
	import igz.fleaxy.locale.LocaleManager;
	import igz.fleaxy.util.StringUtil;
	import mx.formatters.DateFormatter;
	import mx.messaging.config.LoaderConfig;
	import mx.validators.DateValidator;
	/**
	 * ...
	 * @author 
	 */
	public class CalendarUi extends Sprite {
		
		protected var _DayWeeksContainer : Sprite;
		protected var _CalendarContainer : Sprite;
		protected var _Background        : Sprite;
		protected var _BackgroundCalendar: Sprite;
		protected var _Close : ButtonUi;
		protected var _Clean: ButtonUi;
		protected var _CalendarNavigatorUi : CalendarNavigatorUi;
		
		protected var _SpecialDates : Array;
		protected var _SpecialDate_onClick : Function;
		
		protected var _Selected_CalendarDayUi:CalendarDayUi;
		public function set $Selected_CalendarDayUi(p_Calendar:CalendarDayUi) : void {
			_Selected_CalendarDayUi= p_Calendar;
		}
		
		public function get $Selected_CalendarDayUi() : CalendarDayUi {
			return _Selected_CalendarDayUi;
		}
		
		protected var _Date : Date;
		public function get $Date() : Date {
			return _Date;
		}
		
		public function set $Date(s_Date:Date): void {
			_Date = s_Date;
		}
		
		protected var _Fecha : Date;
		public function get $Fecha() : Date {
			return _Fecha;
		}
		
		public function set $Fecha(s_Fecha:Date) : void {
			_Fecha = s_Fecha;
		}
		
		protected var _CleanBg :Bitmap;
		
		protected var _Settings:Object = { "bgColor" : 0x000000 // Color de fondo de calendario
										  ,"bgAlpha" : 0 // Transparencia de fondo de calendario
										  ,"bgImage" : null
										  ,"paddingLeft" : 1
										  ,"paddingTop" : 1 
										  ,"dayMarginX" : 5
										  ,"dayMarginY" : 0
										  ,"bgColorDayWeeks" : 0xFFFFFF // Color de fondo de barra de dias de semana
										  ,"bgAlphaDayWeeks" : 1 // Transparencia de fondo de barra de semana
										  ,"bgColorDaysContainer" : 0xFFFFFF // Color de fondo de los dias de calendarios
										  ,"bgAlphaDaysContainer" : 1 // Transparencia de color de fondo de los dias de calendario
										  ,"controlMonthVisible" : true //Si pone a false, cuando estamos usando CalendarMultiUi, pues este ya tienes una barra de navegación
										  ,"monthNavigatorAlign" : "left" //Alignamento del  mes
										  ,"bgColorNavigator" : 0xFFFFFF //Color de fondo de barra de navegación
										  ,"bgAlphaNavigator" : 0 //Transparencia de fondo de barra de navegación
										  ,"iconPrev" : null // Icon para volver en mes
										  ,"iconNext" : null // Icon para avanzar en mes
										  ,"selectedMonth" : null//(Date) date con el mes que queremos mostrar en el calendario
										  ,"defaultDate" : null //(Date) Fecha (si aplica) Cuando esteja a uno el calendario si auto fijara en la labelDate
										  ,"specialDates" : null // Array de SpecialDate
										  
										  ,"daySettings" : { 
											  "dayLabelStyle" : "defaultTextDay"
													  }
													  
										  ,"dayWeekSettings" : { "dayWeekWidth" : 23 //Ancho de la caja de dias de semana
															    ,"dayWeekHeight" : 19 //Altura de la caja de dias de semana
															    ,"dayWeekBgColor" : 0xFFFFFF //Color de fondo de los dias de semana
																,"dayWeekBgAlpha" : 1 //Transparencia de fondo de dias de semana
															    ,"dayWeekLabelStyle" : "defaultText" //Style
																,"labelWeekDays" : "" // "D,L,M,M,J,V,S" Si no le pasamos elle corre por defecto de sistema
													  }
										};
										
		/**
		 * Componente Calendar
		 *
		 * @param   p_settings = { "bgColor" : 0x000000 // Color de fondo de calendario
		 *								  ,"bgAlpha" : 0 // Transparencia de fondo de calendario
		 *								  ,"bgImage" : null
		 *								  ,"paddingLeft" : 1
		 *								  ,"paddingTop" : 1 
		 *								  ,"dayMarginX" : 5
		 *								  ,"dayMarginY" : 0
		 *								  ,"bgColorDayWeeks" : 0xFFFFFF // Color de fondo de barra de dias de semana
		 *								  ,"bgAlphaDayWeeks" : 1 // Transparencia de fondo de barra de semana
		 *								  ,"bgColorDaysContainer" : 0xFFFFFF // Color de fondo de los dias de calendarios
		 *								  ,"bgAlphaDaysContainer" : 1 // Transparencia de color de fondo de los dias de calendario
		 *								  ,"controlMonthVisible" : true //Si pone a false, cuando estamos usando CalendarMultiUi, pues este ya tienes una barra de navegación
		 *								  ,"monthNavigatorAlign" : "left" //Alignamento del  mes
		 *								  ,"bgColorNavigator" : 0xFFFFFF //Color de fondo de barra de navegación
		 *								  ,"bgAlphaNavigator" : 0 //Transparencia de fondo de barra de navegación
		 *								  ,"iconPrev" : null // Icon para volver en mes
		 *								  ,"iconNext" : null // Icon para avanzar en mes
		 *								  ,"selectedMonth" : null//(Date) date con el mes que queremos mostrar en el calendario
		 *								  ,"defaultDate" : null //(Date) Fecha (si aplica) Cuando esteja a uno el calendario si auto fijara en la labelDate
		 *								  ,"specialDates" : null // Array de SpecialDate
		 * 
		 * 								  ,"daySettings" : {	"dayWidth" : 23 //Ancho de la caja del dia
		 *								  ,"dayHeight" : 23 //Altura de la caja del dia
		 *								  ,"dayBg" : 0xFFFFFF //Color de fondo de la caja
		 *								  ,"bgAlpha" : 1 //Tranparencia de la caja de fondo 
		 *								  ,"dayBgWeekEnd" : 0xFAAC58 //Color de los dias en fin de semana
		 *								  ,"dayBgColorOver" : 0xe34c26 //Color de fondo de la caja
		 *								  ,"dayAlphaOver" : 0 //Color //Tranparencia de la caja
		 *								  ,"dayBgColorBorderOver" : 0xD3DBDE //Color del border
		 *								  ,"dayBgBorderOver" : 0 //Ancho del liena de border
		 *								  ,"dayLabelStyle" : "defaultTextDay" //Style de un dia normal
		 *								  ,"dayLabelStyleOver" : "defaultTextDay" //Style de un dia normal
		 *								  ,"dayLabelStyleToday" : "defaultTextToday" //Style de lo dia de hoy
		 *								  ,"dayLabelStyleTodayOver" : "defaultTextToday" //Style de lo dia de hoy
		 *								  ,"dayLabelStyleSpecial" : "defaultTextSpecial" //Style de los special day
		 *								  ,"dayLabelStyleSpecialOver" : "defaultTextSpecial" //Style de los special day
		 *								  ,"specialDate" : null // SpecialDate
		 *								  ,"onSelectDay" : null // function ( p_date:Date ) {}
		 *								  ,"unSelectDay" : null // function ( p_date:Date ) {}
		 *								  , "onSelectSpecialDay" : null // function ( p_specialDate:SpecialDate ) {}
		 * 									}
		 * 
		 * 								 ,"dayWeekSettings" : { "dayWeekWidth" : 23 //Ancho de la caja de dias de semana
		 *								 ,"dayWeekHeight" : 19 //Altura de la caja de dias de semana
		 *								 ,"dayWeekBgColor" : 0xFFFFFF //Color de fondo de los dias de semana
		 *								 ,"dayWeekBgAlpha" : 1 //Transparencia de fondo de dias de semana
		 *								 ,"dayWeekLabelStyle" : "defaultText" //Style
		 *								 ,"labelWeekDays" : "" // "D,L,M,M,J,V,S" Si no le pasamos elle corre por defecto de sistema
		 *											  }
		 *								}
		 * 
		 *							};
		 *
		 * @example
		 *
		 * //Si no pasas images en parametros las fechas si quedan en texto << >>
		 * [Embed( source = "../../../../../image/widget/calendario/back.png", mimeType="image/png") ]
		 *static private var _CalendarioBack:Class;
		 *static public function get $CalendarioBack() : Bitmap {
		 *	return new _CalendarioBack() as Bitmap;
		 *}
		
		 *[Embed( source = "../../../../../image/widget/calendario/next.png", mimeType="image/png") ]
		 *static private var _CalendarioNext:Class;
		 *static public function get $CalendarioNext() : Bitmap {
		 *	return new _CalendarioNext() as Bitmap;
		 *}
		 * 
		 * var _CalendarioMultiUi:CalendarMultiUi = new CalendarMultiUi(2, {"bgAlpha" : 0, "labelStyle" : styleTitle, "labelMonths" : months, "iconPrev" : $CalendarioBack, "iconNext" : $CalendarioNext,  "calendarSettings" : { "bgColor" : 0xD3DBDE, "borderColor" : 0xCBD5D7, "bgColorDaysContainer" : 0xD3DBDE, "daySettings" : { "dayBg" : 0xE9EDEE, "dayBgWeekEnd" : 0xE9EDEE, "dayBgColorBorderOver" : 0xD3DBDE, "dayBgBorderOver" : 1 , "onSelectSpecialDay" : _onSelectSpecialDate, "unSelectDay" : _onUnselectDate }, "dayWeekSettings" : { "dayWeekBgColor" : 0xCBD5D7, "labelWeekDays" : weekDays, "dayWeekLabelStyle" : "defaultTextWeek"}}} );
		 *
		 * addChild( _CalendarMultiUi );
		 *
		 */
		
		public function get $Settings():Object {
			return _Settings;
		}
		
		
		
		//p_specialDates -> Array de objetos SpecialDate
		public function CalendarUi( p_settings:Object = null ) {
			
			ObjectUtil.$Merge(p_settings, _Settings);
			if (_Settings["selectedMonth"] == null)
			{
					_Settings["selectedMonth"] = new Date();
			}
			_Date = DateTimeUtil.$Clone(_Settings["selectedMonth"]);
			
			
			if (DateTimeUtil.$Validate(_Settings["defaultDate"])) {
				_Fecha = DateTimeUtil.$ToDate(_Settings["defaultDate"]);
			}
			
			
			//var _DateArray:Array;
			//_DateArray = (_Settings["month"] as String).split("/");
			//
			//DateTimeUtil.$ToDate
			//if (_DateArray.length == 3)
			//{
				//try {
					//_Fecha = DateTimeUtil.$Clone(new Date(_DateArray[2], _DateArray[1] - 1, _DateArray[0]));
					//_Date = DateTimeUtil.$Clone(_Fecha);
				//} catch (errObject:Error) {
					//_Fecha = null;
					//_Date = new Date();
				//}
			//} else {
				//_Fecha = null;
				//_Date = new Date();
			//}
			
			
			
			//_SpecialDates = [];
			//if ( p_specialDates != null ) {
				//_SpecialDates = p_specialDates;
			//}
			
			//if ( _Settings["specialDates"] is Array ) {
				//trace("1 specialDates-> " + ((_Settings["specialDates"] as Array)[0] as SpecialDate).$Date);
				//_Settings["specialDates"] = (_Settings["specialDates"] as Array).sortOn("$OrderDate");
				//trace("1 specialDates-> " + ((_Settings["specialDates"] as Array)[0] as SpecialDate).$Date);
				//trace("3 specialDates-> " + (_Settings["specialDates"] as Array).sortOn("$OrderDate"))
			//}
			
			//_SpecialDate_onClick = f_specialDate_onClick;
			
			_Background = new Sprite();
			//if ( _Settings["bgImage"] != null ) {
				//_Background.addChild( _Settings["bgImage"] );
			//}
			addChild( _Background );
			
			_BackgroundCalendar = new Sprite();
			_Background.addChild(_BackgroundCalendar);
			
			_DayWeeksContainer = new Sprite();
			_Background.addChild( _DayWeeksContainer );
			
			_CalendarContainer = new Sprite();
			addChild( _CalendarContainer );
			//			
			var prev : Sprite = new Sprite();
			prev.addChild( new LabelUi("&lt;", _Settings["daySettings"]["dayLabelStyle"]) );
			
			var next : Sprite = new Sprite();
			next.addChild( new LabelUi("&gt;", _Settings["daySettings"]["dayLabelStyle"]) );
			
			_CalendarNavigatorUi = new CalendarNavigatorUi( this, prev, next, _Settings["daySettings"]["dayLabelStyle"] );
			if (_Settings["controlMonthVisible"] == false) {
				_CalendarNavigatorUi.visible = false;
				_CalendarNavigatorUi.height = 0;
			}
			addChild( _CalendarNavigatorUi );
			
			$Draw();
			
			//if (_Settings["controlMonthVisible"] == false) {
				//$Selected_CalendarDayUi.$getMetodo();
			//}
		}
		
		public function $Draw( p_calendarView:String = "CalendarView_MONTH" ) : void {
			
			switch ( p_calendarView ) {
				case CalendarView.DAY :

					break;
				case CalendarView.WEEK :

					break;
				case CalendarView.MONTH :
					_DrawMonthView();
					break;
				case CalendarView.YEAR :

					break;
			}
		}
		
		private function _DrawMonthView() : void {
			SpriteUtil.$RemoveChildsOf( _CalendarContainer );
			SpriteUtil.$RemoveChildsOf( _DayWeeksContainer );
			
			var _Day : CalendarDayUi;
			var _WeekDay : CalendarWeekDayUi;
			var _WeekDayNum : Number;
			var _Row : Number = 0;
			
			var date:Date = DateTimeUtil.$Clone( _Date );
			date.setDate(1);
			
			var f:Number;
			for ( f = 1; f < 8; f++ ) {
				_WeekDay = new CalendarWeekDayUi( f, _Settings["dayWeekSettings"] );
				_DayWeeksContainer.addChild( _WeekDay );
				_WeekDay.x = _Settings["paddingLeft"] + ((_WeekDay.width + _Settings["dayMarginX"]  ) * (f - 1));
			}
			
			var F:uint = 0;
			if (_Settings["specialDates"] as Array) {
				F = (_Settings["specialDates"] as Array).length;
			}
			
			while (  date.getMonth() == _Date.getMonth() ) {
				_WeekDayNum = date.getDay() == 0 ? 7 : date.getDay();
				_Settings["daySettings"]["specialDate"] = null;
				
				
				for ( f = 0; f < F; f++) {
					
					var sDate : SpecialDate = (_Settings["specialDates"] as Array)[f] as SpecialDate;
					if (sDate.$Date.fullYear == date.fullYear && sDate.$Date.month == date.month && sDate.$Date.date == date.date) {
						_Settings["daySettings"]["specialDate"] = sDate;
					}
				}
				
				_Day = new CalendarDayUi( this, date.getDate(), _Settings["daySettings"] );
				
				if (_Fecha != null)
				{
					if (DateTimeUtil.$ToString(_Fecha) == DateTimeUtil.$ToString(date))
					{
						_Selected_CalendarDayUi = _Day;
						_Selected_CalendarDayUi.$Select();
					}
				}
				
				if (_Row == 0) {
					var columnweekday:Sprite;
					columnweekday = new Sprite();
					_CalendarContainer.addChild(columnweekday);
				}
				

				_CalendarContainer.addChild( _Day );
				_Day.x = _Settings["paddingLeft"] + (( _WeekDay.width + _Settings["dayMarginX"] )* (_WeekDayNum - 1 )) + 1;
				_Day.y = _Settings["paddingTop"] + ( _Day.height + _Settings["dayMarginY"] ) * _Row;
				
				date.setDate(date.getDate() + 1);
				
				if ( _WeekDayNum >= 7 && date.getMonth() == _Date.getMonth()) {
					_Row++;
				}
				
			}
			
			_CalendarNavigatorUi.x = 1;
			_CalendarNavigatorUi.y = 0;
			
			
			//_CalendarNavigatorUi.graphics.clear();
			//_CalendarNavigatorUi.graphics.beginFill( _Settings["bgColorNavigator"], _Settings["bgAlphaNavigator"]);
			//_CalendarNavigatorUi.graphics.drawRect( 0, 0, _DayWeeksContainer.width, _DayWeeksContainer.height);
			//_CalendarNavigatorUi.graphics.endFill();
			
			
			_DayWeeksContainer.x = 1;
			_DayWeeksContainer.y = _CalendarNavigatorUi.y + _CalendarNavigatorUi.height + 1;
			
			
			_CalendarContainer.y = _DayWeeksContainer.y + _DayWeeksContainer.height;
			_BackgroundCalendar.x = 1;
			_BackgroundCalendar.y = _DayWeeksContainer.y + _DayWeeksContainer.height;
			
			_DayWeeksContainer.graphics.clear();
			_DayWeeksContainer.graphics.beginFill( _Settings["bgColorDaysContainer"], _Settings["bgAlphaDaysContainer"]);
			_DayWeeksContainer.graphics.drawRect( 0, 0, _DayWeeksContainer.width + _Settings["paddingLeft"], _DayWeeksContainer.height);
			_DayWeeksContainer.graphics.endFill();
			
			_CalendarNavigatorUi.graphics.clear();
			_CalendarNavigatorUi.graphics.beginFill( _Settings["bgColorNavigator"], _Settings["bgAlphaNavigator"]);
			_CalendarNavigatorUi.graphics.drawRect( 0, 0, _DayWeeksContainer.width, _DayWeeksContainer.height);
			_CalendarNavigatorUi.graphics.endFill();
			
			
			if (_Settings["controlMonthVisible"]) {
				_CalendarNavigatorUi._AlignMonth(_Settings["monthNavigatorAlign"]);
			}
			
			_BackgroundCalendar.graphics.clear();
			_BackgroundCalendar.graphics.beginFill( _Settings["bgColorDaysContainer"], _Settings["bgAlphaDaysContainer"] );
			_BackgroundCalendar.graphics.drawRect( 0, 1, _DayWeeksContainer.width, _CalendarContainer.height + 2 );
			_BackgroundCalendar.graphics.endFill();
			
		
			//if ( _Settings["bgImage"] == null ) {
				//_Background.graphics.clear();
				//_Background.graphics.beginFill( _Settings["bgColor"], _Settings["bgAlpha"] );
				//_Background.graphics.drawRect( 0, 0, _DayWeeksContainer.width + 2, height + 1 + _Settings["paddingTop"]);
				//_Background.graphics.endFill();
			//}
			
			
			//if ( _Settings["navigatorAlign"] == "center" ) {
				//_CalendarNavigatorUi.x = _CalendarContainer.width - _CalendarNavigatorUi.width >> 1;
			//} else if ( _Settings["navigatorAlign"] == "left" ) {
				//_CalendarNavigatorUi.x = 0;
			//} else if ( _Settings["navigatorAlign"] == "right" ) {
				//_CalendarNavigatorUi.x = +_Settings["paddingLeft"] + _CalendarContainer.width - _CalendarNavigatorUi.width;
			//}
			
			_Background.graphics.clear();
			_Background.graphics.beginFill( _Settings["bgColor"], _Settings["bgAlpha"] );
			_Background.graphics.drawRect( 0, 0, _DayWeeksContainer.width + _Settings["paddingLeft"] + 2 , height + 1 + _Settings["paddingTop"]);
			_Background.graphics.endFill();
		}
		
		public function $GoPreviousMonth() :void {
			_Date.setDate(1);
			_Date.setMonth( _Date.getMonth() - 1 );
			$Draw();
			
		}

		public function $GoNextMonth() :void {
			_Date.setDate(1);
			_Date.setMonth( _Date.getMonth() + 1 );
			$Draw();
			
		}
		
		public function $AddSpecialDates( p_array : Array ) : void {
			_SpecialDates = p_array;
			$Draw();
		}
		
		// Metodo usado para multi-calendarios
		public function $Select() :void {
			_Selected_CalendarDayUi.$Select();
		}
		
		// Metodo usado para multi-calendarios
		public function $Unselect():void {
			if (_Selected_CalendarDayUi != null) {
				_Selected_CalendarDayUi.$Unselect();
			}
		}
		
		public function $getMetodo():void {
			if ($Selected_CalendarDayUi != null) {
				$Selected_CalendarDayUi.$getMetodo();
			}
		}
		
		public function $setStyleDay(p_style:String):void {
			for ( var i:int = 0; i < _CalendarContainer.numChildren; i++) {
				if (_CalendarContainer.getChildAt(i) is CalendarDayUi) {
					CalendarDayUi(_CalendarContainer.getChildAt(i)).$setStyleDay(p_style);
				}
			}
		}
		
		public function $setStyleWeekDay(p_style:String):void {
			for ( var i:int = 0; i < _DayWeeksContainer.numChildren; i++) {
				if (_DayWeeksContainer.getChildAt(i) is CalendarWeekDayUi) {
					CalendarWeekDayUi(_DayWeeksContainer.getChildAt(i)).$setStyleDayWeek(p_style);
				}
			}
		}
		
		public function $SetSpecialDates(p_specialDates:Array):void {
			_Settings["specialDates"] = p_specialDates;
			_DrawMonthView();
		}
	
}
}